<template>
  <div class="bilibili-player-container">
    <div class="video-container">
      <video v-preventright id="videoPlayer" ref="videoPlayer" class="video-js vjs-bilibili-theme" :poster="poster" />
    </div>

  </div>
</template>

<script>
import videojs from 'video.js'
import 'video.js/dist/video-js.css'
import 'videojs-contrib-hls'
import '@/assets/bilibili-theme.css'
export default {
  name: 'BilibiliStylePlayer',
  props: {
    value: String,
    refId: String,
    drag: Boolean,
    poster: String,
    isPause: {
      type: Boolean,
      default: false
    },
    title: {
      type: String,
      default: '视频标题'
    },
    playCount: {
      type: [String, Number],
      default: '0'
    },
    likeCount: {
      type: [String, Number],
      default: '0'
    },
    coinCount: {
      type: [String, Number],
      default: '0'
    },
    showInfo: {
      type: Boolean,
      default: true
    }
  },

  data() {
    return {
      player: null,
      duration: 0,
      options: {
        controls: true,
        loop: false,
        aspectRatio: '16:9',
        fluid: true, // 流体模式，自适应容器
        playbackRates: [0.5, 1, 1.5, 2], // 播放速度选项
        controlBar: {
          remainingTimeDisplay: false,
          progressControl: {
            seekBar: {
              loadProgressBar: false,
              playProgressBar: true
            }
          },
          children: [
            'playToggle',
            'volumePanel',
            'currentTimeDisplay',
            'timeDivider',
            'durationDisplay',
            'progressControl',
            'liveDisplay',
            'playbackRateMenuButton',
            'fullscreenToggle'
          ]
        },
        html5: {
          hls: {
            enableLowLatencyHls: true
          }
        },
        sources: [{
          src: '',
          type: 'video/mp4'
        }]
      }
    }
  },

  watch: {
    isPause: {
      immediate: true,
      handler(val) {
        if (val) {
          this.player.pause()
        } else {
          this.player.play()
        }
      }
    },
    value: {
      handler(val) {
        this.$emit('pause')
        this.fillVideo(val)
        this.player.src(this.options.sources)
        this.$nextTick(() => {
          this.$refs.videoPlayer.load()
        })
      },
      deep: true
    },
    poster(newVal) {
      if (this.player) {
        this.player.poster(newVal)
      }
    }
  },

  mounted() {
    this.$refs.videoPlayer.controlsList = 'nodownload'
    this.initVideo()
  },

  beforeDestroy() {
    if (this.player) {
      this.player.dispose()
    }
  },

  methods: {
    fillVideo(url) {
      this.options.sources[0].src = url
      let videoType = 'video/mp4'
      if (/^.+(\.m3u8)$/.test(url)) {
        videoType = 'application/x-mpegURL'
      }
      this.options.sources[0].type = videoType
    },

    initVideo() {
      const that = this
      this.fillVideo(this.value)

      // 初始化播放器
      this.player = videojs(this.$refs.videoPlayer, this.options, function onPlayerReady() {
        let last = 0

        this.on('loadedmetadata', function () {
          that.duration = this.duration()
          that.$emit('loaded', this.duration())

          const lastTime = localStorage.getItem(that.refId)
          if (lastTime != null && lastTime > 5) {
            last = lastTime
            this.currentTime(lastTime)
          }
        })

        this.on('timeupdate', function () {
          const curTime = this.currentTime()
          const end = that.duration - curTime

          if (end < 1) {
            this.currentTime(0)
            last = 0
            return
          }

          if (that.drag && (curTime - last > 2 || last - curTime > 2)) {
            this.currentTime(last)
            return
          }

          if (curTime > 0) {
            localStorage.setItem(that.refId, curTime)
          }

          last = curTime
        })

        this.on('play', function () {
          that.$emit('play')
        })

        this.on('pause', function () {
          that.$emit('pause')
        })

        this.on('contextmenu', function () {
          return false
        })
      })

      // 自定义控制栏按钮
      this.addCustomControls()

      this.player.on('error', () => {
        const error = this.player.error()
        if (error.message.indexOf('The media could not be loaded') > -1) {
          this.$emit('loadError', true)
        }
      })
    },

    addCustomControls() {
      // 添加B站风格的按钮
      const controlBar = this.player.controlBar

      // 添加点赞按钮
      const likeButton = controlBar.addChild('button', {}, 0)
      likeButton.addClass('vjs-like-button')
      likeButton.setAttribute('title', '点赞')
      likeButton.innerHTML = '<i class="icon-like"></i>'
      likeButton.on('click', () => {
        this.$emit('like')
      })

      // 添加收藏按钮
      const favoriteButton = controlBar.addChild('button', {}, 0)
      favoriteButton.addClass('vjs-favorite-button')
      favoriteButton.setAttribute('title', '收藏')
      favoriteButton.innerHTML = '<i class="icon-favorite"></i>'
      favoriteButton.on('click', () => {
        this.$emit('favorite')
      })
    }
  }
}
</script>

<style lang="scss">

.bilibili-player-container {
  width: 100%;

  margin: 0 auto;
  background: #f4f4f4;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);

  .video-container {
    position: relative;
    background: #000;

    .vjs-bilibili-theme {
      .vjs-big-play-button {
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 60px;
        height: 60px;
        border-radius: 50%;
        border: none;
        background: rgba(0, 0, 0, 0.5);
        color: #fff;
        font-size: 30px;
        line-height: 60px;

        &:hover {
          background: rgba(251, 114, 153, 0.8);
        }
      }

      .vjs-control-bar {
        height: 40px;
        background: rgba(0, 0, 0, 0.7);
        color: #fff;

        .vjs-play-control {
          order: 1;
        }

        .vjs-volume-panel {
          order: 2;
        }

        .vjs-current-time {
          order: 3;
        }

        .vjs-time-divider {
          order: 4;
        }

        .vjs-duration {
          order: 5;
        }

        .vjs-progress-control {
          position: absolute;
          top: -10px;
          left: 0;
          right: 0;
          width: 100%;
          height: 10px;
          order: 0;

          .vjs-progress-holder {
            height: 3px;
            margin: 0;
            background: rgba(255, 255, 255, 0.2);

            .vjs-play-progress {
              background: #fb7299;

              &:before {
                font-size: 0;
                width: 10px;
                height: 10px;
                top: -3px;
                border-radius: 50%;
                background: #fb7299;
              }
            }
          }
        }

        .vjs-playback-rate {
          order: 6;
        }

        .vjs-fullscreen-control {
          order: 7;
        }

        .vjs-like-button,
        .vjs-favorite-button {
          width: auto;
          font-size: 16px;
          color: #fff;
          cursor: pointer;
          margin: 0 5px;

          &:hover {
            color: #fb7299;
          }
        }
      }
    }
  }

  .video-info {
    padding: 12px 16px;
    background: #fff;

    .video-title {
      margin: 0 0 8px;
      font-size: 18px;
      font-weight: 500;
      color: #212121;
      line-height: 1.4;
    }

    .video-stats {
      display: flex;
      align-items: center;
      font-size: 12px;
      color: #999;

      .stat-item {
        display: flex;
        align-items: center;
        margin-right: 15px;

        i {
          margin-right: 4px;
          font-size: 14px;
        }
      }
    }
  }
}

/* 图标样式 */
.icon-play,
.icon-like,
.icon-coin,
.icon-favorite {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-size: contain;
  background-repeat: no-repeat;
  vertical-align: middle;
}

.icon-play {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23999'%3E%3Cpath d='M8 5v14l11-7z'/%3E%3C/svg%3E");
}

.icon-like {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23999'%3E%3Cpath d='M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z'/%3E%3C/svg%3E");
}

.icon-coin {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23999'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.31-8.86c-1.77-.45-2.34-.94-2.34-1.67 0-.84.79-1.43 2.1-1.43 1.38 0 1.9.66 1.94 1.64h1.71c-.05-1.34-.87-2.57-2.49-2.97V5H10.9v1.69c-1.51.32-2.72 1.3-2.72 2.81 0 1.79 1.49 2.69 3.66 3.21 1.95.46 2.34 1.15 2.34 1.87 0 .53-.39 1.39-2.1 1.39-1.6 0-2.23-.72-2.32-1.64H8.04c.1 1.7 1.36 2.66 2.86 2.97V19h2.34v-1.67c1.52-.29 2.72-1.16 2.73-2.77-.01-2.2-1.9-2.96-3.66-3.42z'/%3E%3C/svg%3E");
}

.icon-favorite {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23999'%3E%3Cpath d='M17 3H7c-1.1 0-1.99.9-1.99 2L5 21l7-3 7 3V5c0-1.1-.9-2-2-2z'/%3E%3C/svg%3E");
}
</style>
